/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { defineComponent, computed, ref, watch, onMounted, inject } from 'vue';
import type { SetupContext } from 'vue';
import { buttonEditProps, ButtonEditProps } from '../button-edit.props';
import { useButton } from '../composition/use-button';
import { useClear } from '../composition/use-clear';
import { useTextBox } from '../composition/use-text-box';
import { usePopup } from '../composition/use-popup';
import getTextEditorRender from '../components/text-edit.component';
import getTagEditorRender from '../components/tag-edit.component';
import getButtonGroupRender from '../components/button-group.component';

import '../button-edit.css';
import { DesignerItemContext } from '../../../designer-canvas/src/types';
import { useDesignerComponent } from '../../../designer-canvas/src/composition/function/use-designer-component';

export default defineComponent({
    name: 'FButtonEdit',
    props: buttonEditProps,
    emits: [
        'updateExtendInfo',
        'clear',
        'change',
        'click',
        'clickButton',
        'blur',
        'focus',
        'mouseEnterIcon',
        'mouseLeaveIcon',
        'keyup',
        'keydown',
        'inputClick',
        'input',
        'update:modelValue'
    ] as (string[] & ThisType<void>) | undefined,
    setup(props: ButtonEditProps, context: SetupContext) {
        const elementRef = ref();
        const designItemContext = inject<DesignerItemContext>('design-item-context') as DesignerItemContext;
        // const designerRulesComposition = useDesignerRules(designItemContext.schema, designItemContext.parent?.schema);
        const componentInstance = useDesignerComponent(elementRef, designItemContext);
        const customClass = ref<string>(props.customClass);
        const modelValue = ref(props.modelValue);
        const popupComposition = usePopup(props, context, elementRef);
        const useButtonComposition = useButton(props, context, elementRef, popupComposition);
        const displayText = ref('');
        const useTextBoxComposition = useTextBox(props, context, modelValue, displayText, popupComposition);
        const { hasFocusedTextBox, inputGroupClass } = useTextBoxComposition;
        const useClearComposition = useClear(props, context, modelValue, hasFocusedTextBox, displayText, useTextBoxComposition);

        onMounted(() => {
            elementRef.value.componentInstance = componentInstance;
        });

        context.expose(componentInstance.value);

        const buttonEditClass = computed(() => {
            const classObject = {
                'f-button-edit': true,
                'f-cmp-inputgroup': true,
                'f-button-edit-nowrap': !props.wrapText
            } as Record<string, boolean>;
            if (customClass.value) {
                customClass.value.split(' ').reduce<Record<string, boolean>>((result: Record<string, boolean>, className: string) => {
                    result[className] = true;
                    return result;
                }, classObject);
            }
            return classObject;
        });

        function getEditorRender() {
            if (props.multiSelect && props.inputType === 'tag') {
                return getTagEditorRender(props, modelValue, useTextBoxComposition);
            }
            return getTextEditorRender(props, modelValue, useTextBoxComposition);
        }

        let renderEditor = getEditorRender();

        watch([() => props.multiSelect, () => props.inputType], () => {
            renderEditor = getEditorRender();
        });

        const renderButtonGroup = getButtonGroupRender(props, useButtonComposition, useClearComposition);

        return () => {
            return (
                <div {...context.attrs} ref={elementRef} class={buttonEditClass.value} id={props.id}>
                    <div class={inputGroupClass.value}>
                        {renderEditor()}
                        {renderButtonGroup()}
                    </div>
                </div>
            );
        };
    }
});
